home *** CD-ROM | disk | FTP | other *** search
/ Gigantic Games 2 / Gigantic Games 2.iso / pc / _m_ / minesweeper / init.cc < prev    next >
C/C++ Source or Header  |  1994-12-23  |  10KB  |  337 lines

  1. // This may look like C code, but it is really -*- C++ -*-
  2. ///////////////////////////////////////////////////////////////////////////
  3. //
  4. //  AMIGA Minesweeper - Open window, init gadgets, ...
  5. //
  6. //  (c) 1992 Hubert Feyrer (c9020@rrzc1.rz.uni-regensburg.de)
  7. //
  8. ///////////////////////////////////////////////////////////////////////////
  9.  
  10. /*
  11. ** Diverse "C"-Header
  12. */
  13. #define class _class
  14. #define template _template
  15. #define IntuitionBase IntuiBase
  16. #define GfxBase GraphBase
  17. extern "C" {
  18. # include <stdio.h>
  19. # include <stdlib.h>
  20. # include <hardware/intbits.h>
  21. # include <exec/types.h>
  22. # include <exec/exec.h>
  23. # include <exec/Interrupts.h>
  24. # include <exec/Memory.h>
  25. # include <exec/Ports.h>
  26. # include <exec/ExecBase.h>
  27. # include <devices/timer.h>
  28. # include <utility/tagitem.h>
  29. # include <intuition/intuition.h>
  30. # include <intuition/intuitionbase.h>
  31. # include <intuition/gadgetclass.h>
  32. # include <graphics/view.h>
  33. # include <libraries/gadtools.h>
  34. # include <clib/gadtools_protos.h>
  35. # include <clib/intuition_protos.h>
  36. # include <clib/exec_protos.h>
  37. # include <math.h>
  38. }    
  39. #undef IntuitionBase
  40. #undef GfxBase 
  41. #undef class
  42. #undef template
  43.  
  44. /*
  45. ** C++-Header
  46. */
  47. #include "mine.h"
  48. #include "field.h"
  49. #include <MLCG.h>
  50. #include <RndInt.h>
  51.  
  52.  
  53.  
  54. //*
  55. //* (zu) VIELE globale Daten...
  56. //*
  57. IntuiBase *IntuitionBase=NULL;         // Typ NICHT IntuitionBase!!!
  58. GraphBase *GfxBase=NULL;               // Typ NICHT GfxBase!!!
  59. Library *GadToolsBase=NULL;
  60. NewWindow nwin={ 0,0,0,0,-1,-1,IDCMP_CLOSEWINDOW|IDCMP_GADGETUP|
  61.          IDCMP_MOUSEBUTTONS,WFLG_CLOSEGADGET|WFLG_OTHER_REFRESH
  62.          |WFLG_DRAGBAR|WFLG_DEPTHGADGET|WFLG_ACTIVATE|WFLG_RMBTRAP
  63.          ,NULL,NULL,NULL,NULL,NULL,0,0,0,0,WBENCHSCREEN };
  64. Window *win=NULL;
  65. Gadget *glist=NULL;
  66. VisualInfo *vinfo=NULL;
  67. Screen *scr=NULL;
  68. timerequest treq;                      // Für Spielzeit-Anfrage
  69. MsgPort *tport;                        // -"- ----"---- ---"---
  70. int fxs=0;                             // field x size
  71. int fys=0;                             // field y size
  72. int X0;                                // linker Rand des Minenfeldes
  73. int Y0;                                // rechter Rand des Minenfeldes
  74. int win_w;                             // Breite des Spiel-Fensters
  75. int win_h;                             // Höhe des Spiel-Fensters
  76. char *argv0=NULL;                      // argv[0]
  77. NewGadget nnumgad={ -1,-1,-1,-1,NULL,NULL,1000,PLACETEXT_IN,NULL,NULL};
  78. Gadget *numgad=NULL;                   // Textgadget, um Restminen anzuzeigen
  79. char tnumgad[5];                       // minesleft
  80. NewGadget ntimegad={ -1,-1,-1,-1,NULL,NULL,1001,PLACETEXT_IN,NULL,NULL};
  81. Gadget *timegad=NULL;                  // Um Spielzeit anzuzeigen
  82. char ttimegad[5];                      // playtime
  83. NewGadget ngogad={ -1,-1,-1,-1,NULL,NULL,1002,PLACETEXT_IN,NULL,NULL};
  84. Gadget *gogad=NULL;                    // Restart-Button (nach Crash)
  85. TextFont *txtfont;                     // mit setfont eingestellter Font
  86. int countdown;                         // Restliche Felder
  87. int minesleft;                         // Anzahl unentdeckter Minen
  88. Offset validfields[]={ {-1,-1}, { 0,-1}, { 1,-1}, {-1, 0},
  89.                { 1, 0}, {-1, 1}, { 0, 1}, { 1, 1} };
  90.  
  91.  
  92.  
  93. //*
  94. //* Resourcen freigeben und Programm beenden.
  95. //*
  96. void shutdown(int rc, char *msg=NULL)
  97. {
  98.     if(treq.tr_node.io_Message.mn_ReplyPort) CloseDevice((IORequest *)&treq);
  99.     if(tport) DeletePort((MsgPort *)tport);
  100.     if(win) CloseWindow(win);
  101.     if(glist) FreeGadgets(glist);
  102.     if(minefield){
  103.     for(int i=0;i<lenx;i++){
  104.         if(minefield[i]){
  105.         for(int j=0;j<leny;j++){
  106.             if(minefield[i][j]){
  107.             delete minefield[i][j];
  108.             }
  109.         }
  110.         delete[] minefield[i];
  111.         }
  112.     }
  113.     delete[] minefield;
  114.     }
  115.     if(vinfo) FreeVisualInfo(vinfo);
  116.     if(GadToolsBase) CloseLibrary(GadToolsBase);
  117.     if(GfxBase) CloseLibrary((Library *)GfxBase);
  118.     if(IntuitionBase) CloseLibrary((Library *)IntuitionBase);
  119.  
  120.     msg && printf("%s: %s\n",argv0,msg);
  121.     exit(rc);
  122. }
  123.  
  124.  
  125. //*
  126. //* Fenster, Gadget, ... initialisieren
  127. //*
  128. void init(int p)
  129. {
  130.     ULONG lock;
  131.     int i,j;
  132.  
  133.     // Diverse Bibliotheken öffnen
  134.     IntuitionBase=(IntuiBase *)OpenLibrary("intuition.library",37);
  135.     if(IntuitionBase==NULL) shutdown(20,"No OS2.0-Intuition found!");
  136.  
  137.     GfxBase=(GraphBase *)OpenLibrary("graphics.library",37);
  138.     if(GfxBase==NULL) shutdown(20,"Need some OS2.0-Gfx!");
  139.  
  140.     GadToolsBase=(Library *)OpenLibrary("gadtools.library",37);
  141.     if(GadToolsBase==NULL) shutdown(20,"Where's my GadTools-Library?!");
  142.  
  143.     // Maßeinheiten ermitteln (f. Fenster, Gadgets, ...)
  144.     lock=LockIBase(0);
  145.     scr=IntuitionBase->ActiveScreen;
  146.     UnlockIBase(lock);
  147.     txtfont=(TextFont *)OpenFont(scr->Font);      // Mit c:setfont festge-
  148.                                                   // legter Zeichensatz
  149.     fxs=2*txtfont->tf_XSize;
  150.     if(scr->ViewPort.Modes&~LACE==0) fxs*=2;    // LoRes
  151.     fys=txtfont->tf_YSize+3;
  152.     CloseFont(txtfont);
  153.     X0=1.5*fxs;
  154.     Y0=3*fys;
  155.     win_w=X0+(1.5*fxs)+(lenx*fxs);
  156.     win_h=Y0+fys+(leny*fys);
  157.  
  158.     // Gadgets initialisieren
  159.     vinfo=GetVisualInfo(scr,TAG_END);
  160.     if(vinfo==NULL){
  161.     shutdown(20,"Can't GetVisualInfo()!");
  162.     }
  163.  
  164.     Field::lastgad=CreateContext(&glist);
  165.     if( Field::lastgad==NULL ){
  166.         shutdown(20,"Can't CreateContext()!");
  167.     }
  168.     
  169.     // Minenfeld errichten
  170.     countdown=0;
  171.     minefield=new Field **[lenx];
  172.     for(i=0;i<lenx;i++){
  173.     minefield[i]=new Field *[leny];
  174.     for(j=0;j<leny;j++){
  175.         minefield[i][j]=new Field(X0+i*fxs,Y0+j*fys,i,j);
  176.     }
  177.     }
  178.  
  179.     // Minenanzeige-Gadget
  180.     sprintf(tnumgad,"%04d",(lenx*leny*p)/100);
  181.     if(tnumgad[0]=='0') tnumgad[0]=' ';
  182.     nnumgad.ng_VisualInfo = vinfo;
  183.     nnumgad.ng_TextAttr   = scr->Font;
  184.     nnumgad.ng_LeftEdge   = fxs;
  185.     nnumgad.ng_TopEdge    = 1.45*fys;
  186.     nnumgad.ng_Width      = 2.8*fxs;
  187.     nnumgad.ng_Height     = fys;
  188.     Field::lastgad=numgad=CreateGadget(TEXT_KIND,Field::lastgad,&nnumgad,
  189.                        GTTX_Text,tnumgad,
  190.                        GTTX_Border, 2,
  191.                        TAG_END);
  192.     if(numgad==NULL) shutdown(20,"Can't create numgad!");
  193.  
  194.     // Zeitanzeige-Gadget
  195.     sprintf(ttimegad,"%04d",playtime);
  196.     ntimegad.ng_VisualInfo = vinfo;
  197.     ntimegad.ng_TextAttr   = scr->Font;
  198.     ntimegad.ng_Width      = 2.8*fxs;
  199.     ntimegad.ng_Height     = fys;
  200.     ntimegad.ng_LeftEdge   = win_w-(fxs+ntimegad.ng_Width);
  201.     ntimegad.ng_TopEdge    = 1.45*fys;
  202.     Field::lastgad=timegad=CreateGadget(TEXT_KIND,Field::lastgad,&ntimegad,
  203.                     GTTX_Text,ttimegad,
  204.                     GTTX_Border, 2,
  205.                     TAG_END);
  206.     if(numgad==NULL) shutdown(20,"Can't create timegad!");
  207.  
  208.     // Restart-Button
  209.     ngogad.ng_VisualInfo = vinfo;
  210.     ngogad.ng_TextAttr   = scr->Font;
  211.     ngogad.ng_GadgetText = "Go!";
  212.     ngogad.ng_Width      = ntimegad.ng_LeftEdge-floor(5.4*fxs);
  213.     ngogad.ng_LeftEdge   = 4.6*fxs;
  214.     ngogad.ng_TopEdge    = 1.45*fys;
  215.     ngogad.ng_Height     = fys;
  216.     Field::lastgad=gogad=CreateGadget(BUTTON_KIND,Field::lastgad,&ngogad,
  217.                       TAG_END);
  218.     // gogad->Flags |= GFLG_DISABLED;
  219.     if(gogad==NULL) shutdown(20,"Can't create gogad!");
  220.     
  221.     
  222.     // Fenster aufmachen
  223.     nwin.Width       = win_w;
  224.     nwin.Height      = win_h;
  225.     nwin.LeftEdge    = (scr->Width-win_w)/2;
  226.     nwin.TopEdge     = (scr->Height-win_h)/2;
  227.     nwin.Title       = WIN_T;
  228.     if(nwin.LeftEdge<=0 || nwin.TopEdge<=0)
  229.       shutdown(20,"Choose smaller dimension or font!");
  230.     nwin.FirstGadget = glist;
  231.     win=OpenWindowTags(&nwin,TAG_END);
  232.     if(win==NULL) shutdown(20,"Can't open window!");
  233.  
  234.     // Timer-Device öffnen und Uhr initialisieren
  235.     tport=CreatePort("Mine timer-port",0);
  236.     if(tport==NULL) shutdown(20,"Can't create timer-port!");
  237.     if(OpenDevice("timer.device",UNIT_VBLANK,(IORequest *)&treq,0))
  238.       shutdown(20,"No timer.device?!?");
  239.     treq.tr_node.io_Message.mn_ReplyPort = tport;
  240.     treq.tr_node.io_Command              = TR_ADDREQUEST;
  241.     treq.tr_node.io_Flags                = 0;
  242.     treq.tr_node.io_Error                = 0;
  243.     treq.tr_time.tv_secs                 = 1;     // 1 Sekunde warten
  244.     treq.tr_time.tv_micro                = 0;
  245.     playtime=0;
  246.  
  247.     return;
  248. }
  249.  
  250.  
  251. //*
  252. //* Felder aufdecken, Minen anzeigen
  253. //*
  254. void showmines(void)
  255. {
  256.     for(int i=0;i<lenx;i++){
  257.     for(int j=0;j<leny;j++){
  258.         minefield[i][j]->open(1);
  259.     }
  260.     }
  261. }
  262.  
  263.  
  264. //*
  265. //* Felder zuschütten, Markierung löschen
  266. //*
  267. void removemines(void)
  268. {
  269.     for(int i=0;i<lenx;i++){
  270.     for(int j=0;j<leny;j++){
  271.         minefield[i][j]->clear();
  272.     }
  273.     }
  274.     RefreshGadgets(glist,win,NULL);
  275. }
  276.  
  277.  
  278. //*
  279. //* Anzahl der Nachbarminen bei freien Feldern errechnen
  280. //*
  281. void calc_cnt(void)
  282. {
  283.     for(int j=0;j<leny;j++){
  284.     for(int i=0;i<lenx;i++){
  285.         if(minefield[i][j]->cnt()!=-1){
  286.         int no=0;        // Anzahl Minen in angrenzenden Feldern
  287.  
  288.         // Umgebung jedes einzelnen Feldes absuchen
  289.         for(int v=0;v<8;v++){
  290.             int vi=i+validfields[v].dx;
  291.             int vj=j+validfields[v].dy;
  292.             
  293.             if(inminefield(vi,vj)){
  294.             if(minefield[vi][vj]->cnt()==-1){
  295.                 no++;
  296.             }
  297.             }
  298.         }
  299.         minefield[i][j]->cnt(no);
  300.         }
  301.     }
  302.     }
  303. }
  304.  
  305. //*
  306. //* Liefert Zufallszahl in [0;high) mit Algorithmus aus libg++
  307. //*
  308. int rnd(int high)
  309. {
  310.     static MLCG gen(0,(long)time(NULL));    
  311.     static RandomInteger r(0,65535,&gen); 
  312.  
  313.     return int(r.asLong(long(high-1)));
  314. }
  315.  
  316.  
  317. //*
  318. //* Minenfeld zu p Prozent verminen und Anzahl Minen in
  319. //* Nachbarfeldern berechnen lassen.
  320. //*
  321. void hidemines(int p)
  322. {
  323.     int n=(lenx*leny*p)/100.0;     // Anzahl zu legender Minen
  324.     minesleft=n;
  325.  
  326.     while(n){
  327.     int x=rnd(lenx);
  328.     int y=rnd(leny);
  329.     
  330.     if(minefield[x][y]->cnt()==-1) continue;
  331.     minefield[x][y]->cnt(-1);
  332.     --n;
  333.     }
  334.     
  335.     calc_cnt();
  336. }
  337.